package com.usian.order.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.usian.jyzx.model.entity.order.OrderInfo;
import com.usian.jyzx.model.entity.order.OrderLog;
import com.usian.jyzx.model.entity.product.ProductSku;
import com.usian.jyzx.model.entity.user.UserAddress;
import com.usian.jyzx.model.entity.user.UserInfo;
import com.usian.jyzx.model.vo.common.Result;
import com.usian.jyzx.model.vo.common.ResultCodeEnum;
import com.usian.jyzx.model.vo.h5.OrderItem;
import com.usian.jyzx.model.vo.h5.OrderItemInfo;
import com.usian.jyzx.model.vo.h5.TradeVo;
import com.usian.order.fegin.CartFegin;
import com.usian.order.fegin.ProductFegin;
import com.usian.order.fegin.UserFegin;
import com.usian.order.mapper.OrderLogMapper;
import com.usian.order.service.OrderInfoService;
import com.usian.order.service.OrderItemService;
import com.usian.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @TODO:
 * @Author:baimu
 * @Date:2024 07 16 09 55
 **/
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    CartFegin cartFegin;

    @Autowired
    ProductFegin productFegin;

    @Autowired
    UserFegin userFegin;

    @Autowired
    RedisTemplate redisTemplate;


    @Autowired
    OrderInfoService orderInfoService;

    @Autowired
    OrderItemService orderItemService;

    @Autowired
    OrderLogMapper orderLogMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result submitOrder(OrderItemInfo orderItemInfo, String token) {

        String str =(String) redisTemplate.opsForValue().get("token:" + token);

        UserInfo userInfo = JSON.parseObject(str, UserInfo.class);
        Integer userId = userInfo.getId();
        String nickName = userInfo.getNickName();


        //通过skuId ，去查库存数

        List<OrderItem> orderItemList = orderItemInfo.getOrderItemList();
        Map<Long, Integer> longIntegerHashMap = new HashMap<>();


        orderItemList.forEach(orderItem -> {
            Long skuId = orderItem.getSkuId();
            Integer skuNum = orderItem.getSkuNum();
            ProductSku productSku = productFegin.findProductSkuById(skuId);
            if(productSku.getStockNum()<skuNum){
                longIntegerHashMap.put(skuId,skuNum);
            }

        });

        if(longIntegerHashMap.size()>0){
            return Result.build(ResultCodeEnum.OUT_OF_STOCK.getCode(),ResultCodeEnum.OUT_OF_STOCK.getMessage());
        }
        OrderInfo orderInfo = new OrderInfo();
        String orderNo = IdUtil.getSnowflakeNextIdStr();

        log.info("生成的订单号：{}",orderNo);
        orderInfo.setOrderNo(orderNo);
        orderInfo.setOrderStatus(0);
        orderInfo.setFeightFee(orderItemInfo.getFeightFee());
        orderInfo.setNickName(nickName);


        orderInfo.setOriginalTotalAmount(orderItemList.stream().map(
                orderItem -> orderItem.getOrderPrice().multiply(new BigDecimal(orderItem.getSkuNum()))
        ).reduce(BigDecimal.ZERO, BigDecimal::add));

        UserAddress userAddress = userFegin.findUserAddressById(orderItemInfo.getUserAddressId());


        orderInfo.setReceiverAddress(userAddress.getFullAddress());
        orderInfo.setReceiverDistrict(userAddress.getDistrictCode());
        orderInfo.setReceiverCity(userAddress.getCityCode());
        orderInfo.setReceiverName(userAddress.getName());
        orderInfo.setReceiverPhone(userAddress.getPhone());
        orderInfo.setReceiverTagName(userAddress.getTagName());
        orderInfo.setReceiverProvince(userAddress.getProvinceCode());
        orderInfo.setUserId(Long.valueOf(userId));
        orderInfo.setTotalAmount(orderInfo.getOriginalTotalAmount().add(orderInfo.getFeightFee()));
        orderInfo.setCouponAmount(new BigDecimal(0));
        orderInfo.setCreateTime(new Date());

        orderInfoService.save(orderInfo);

        orderItemList.forEach(orderItem -> {
            com.usian.jyzx.model.entity.order.OrderItem orderItem1 = new com.usian.jyzx.model.entity.order.OrderItem();
            orderItem1.setOrderId(Long.valueOf(orderNo));
            orderItem1.setSkuName(orderItem.getSkuName());
            orderItem1.setSkuId(orderItem.getSkuId());
            orderItem1.setSkuNum(orderItem.getSkuNum());
            orderItem1.setSkuPrice(orderItem.getOrderPrice());
            orderItem1.setThumbImg(orderItem.getThumbImg());
            orderItem1.setCreateTime(new Date());
            orderItemService.save(orderItem1);
        });
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(Long.valueOf(orderNo));
        orderLog.setOperateUser(nickName);


        orderLogMapper.save(orderLog);

        List<Long> skuIds = orderItemList.stream().
                map(OrderItem::getSkuId).collect(Collectors.toList());

        log.info("要删除的SKUID：{}",skuIds);


        cartFegin.delCart(userId,skuIds);


        return Result.build(ResultCodeEnum.SUCCESS.getCode(),ResultCodeEnum.SUCCESS.getMessage(),orderNo);

    }

    @Override
    public TradeVo buy(String token, Long skuId) {
        String str =(String) redisTemplate.opsForValue().get("token:" + token);

        UserInfo userInfo = JSON.parseObject(str, UserInfo.class);
        Integer userId = userInfo.getId();
        String nickName = userInfo.getNickName();
        List<OrderItem> orderItemList =  new ArrayList<OrderItem>();
        OrderItem orderItem = new OrderItem();
        ProductSku productSku = productFegin.findProductSkuById(skuId);

        orderItem.setOrderPrice(productSku.getSalePrice());
        orderItem.setSkuId(skuId);
        orderItem.setSkuName(productSku.getSkuName());
        orderItem.setIsChecked(1);
        orderItem.setSkuNum(1);
        orderItem.setThumbImg(productSku.getThumbImg());
        orderItem.setUserId(userId);
         orderItemList.add(orderItem);

        TradeVo tradeVo = new TradeVo();

        tradeVo.setOrderItemList(orderItemList);
        tradeVo.setTotalAmount(productSku.getSalePrice());

        return tradeVo;
    }
}
